package jobs;

import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.xml.transform.stream.StreamSource;

import net.sf.saxon.s9api.Axis;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.WhitespaceStrippingPolicy;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmSequenceIterator;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;

import pojo.Evento;
import util.Utility;



public class MailJob implements Job {

	private  Logger log = Logger.getLogger(getClass());

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 
     * Constants.
     * 
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    public static final String PROP_URL_DB = "urlDB";
    public static final String PROP_URL_EVENTI = "urlEventi"; 

    public void execute(JobExecutionContext context) {
    	//System.out.println("SONO DENTRO");

    	

    	JobDataMap data = context.getMergedJobDataMap();
    	String dbLoc  = "";
    	ServletContext serv=null;    	
		try {
			serv = (ServletContext)context.getScheduler().getContext().get("ContextServ");
		} catch (SchedulerException e1) {
			// TODO Auto-generated catch block
			log.error(e1.toString());
		}
        dbLoc = serv.getRealPath("db");
        //System.out.println(dbLoc);
    	Properties props = new Properties();
		props.put(Utility.PROP_SMTP_AUTH, data.getString(Utility.PROP_SMTP_AUTH));
		props.put(Utility.PROP_SMTP_STARTTLS, data.getString(Utility.PROP_SMTP_STARTTLS));
		props.put(Utility.PROP_SMTP_HOST,data.getString(Utility.PROP_SMTP_HOST));
		props.put(Utility.PROP_SMTP_PORT, data.getString(Utility.PROP_SMTP_PORT));
        final String user = data.getString(Utility.PROP_SMTP_USERNAME);
        final String pass = data.getString(Utility.PROP_SMTP_PASSWORD);
        //prima di mandare le mail recuperiamo gli indirizzi
        ArrayList<String> leMail = getMails(dbLoc);
        ArrayList<Evento> gliEventi = getEventi(dbLoc); 
	
        Session session = Session.getInstance(props,
				  new javax.mail.Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(user, pass);
					}
		});
	
		//MANDOOO
		try {
		
			for(String mailAd : leMail){
 
			 
			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress(user));
			message.setRecipients(Message.RecipientType.TO,
				InternetAddress.parse(mailAd));
			message.setSubject("SEII BELLLAAAAA");
			message.setSentDate(GregorianCalendar.getInstance(Utility.timeZone).getTime());
			message.setText("QUANTO SEI FIGAAAA");
 
			Transport.send(message);
 
			//System.out.println("Done");
			}
			
		} catch (Exception e) {
			//e.printStackTrace();
			getLog().error("Sending message fail"+e.getMessage() );
			 
		}
		
		//MailInfo mailInfo = populateMailInfo(data, createMailInfo());
        
        //getLog().info("Sending message " + mailInfo);


    }

    protected Logger getLog() {
        return log;
    }

    private static XdmNode getChild(XdmNode parent, QName childName) {
        XdmSequenceIterator iter = parent.axisIterator(Axis.CHILD, childName);
        if (iter.hasNext()) {
            return (XdmNode)iter.next();
        } else {
            return null;
        }
    }
    
    private ArrayList<String> getMails(String url){
		Processor proc = new Processor(false);
        XPathCompiler xpath = proc.newXPathCompiler();
        XdmNode newslDoc = null; 
        XPathSelector selector = null;
        ArrayList<String> mails = new ArrayList<String>();
        DocumentBuilder builder = proc.newDocumentBuilder();
        builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);    	
    	
        try{
        	
        newslDoc = builder.build(new File(url+File.separator+"Newsletter.xml"));    
        selector = xpath.compile("//Mail").load(); 
        selector.setContextItem(newslDoc);
        for (XdmItem item: selector) {
      	  
        String mailVal = ((XdmNode)item).getStringValue();       
        mails.add(mailVal);
        
        }        
        
        }catch (Exception e) {
        	//e.printStackTrace();
        	getLog().error("Sending message fail"+e.getMessage() );

		}
        
        return mails;
    }

	  public ArrayList<Evento> getEventi(String url)
	    {

      ArrayList<Evento> eventi = new ArrayList<Evento>();
      
      String oraXml = Utility.toStringOraXml(GregorianCalendar.getInstance(Utility.timeZone).getTime());
      String oggi = Utility.toStringDataXml(GregorianCalendar.getInstance(Utility.timeZone).getTime());
      Calendar gre = GregorianCalendar.getInstance(Utility.timeZone);
      Date week = null;
      int giornoSet = gre.get(GregorianCalendar.DAY_OF_WEEK);
      //gre.setTime(today);
      gre.add(GregorianCalendar.DATE, 7);
      week = gre.getTime();
	  String quando = Utility.toStringDataXml(week);

	  Processor proc = new Processor(false);
      XPathCompiler xpath = proc.newXPathCompiler();
      DocumentBuilder builder = proc.newDocumentBuilder();
      builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
      XdmNode eventiDoc = null; 
      XPathSelector selector = null;
      QName hp = new QName("hp");
      QName settimanale = new QName("settimanale");
      QName categoria = new QName("categoria");
      QName tipo = new QName("tipo");
      QName id = new QName("id");
      QName data = new QName("Data");
      QName dataFine = new QName("DataFine");
      QName giorno = new QName("Giorno");
      QName ora = new QName("Ora");
      QName indirizzo = new QName("Indirizzo");
      QName nomeLuogo = new QName("NomeLuogo");
      QName titolo = new QName("Titolo");
      QName keywords = new QName("Keywords");
      QName descrizione = new QName("Descrizione");
      QName descBreve = new QName("DescrizioneBreve");
      QName prezzo = new QName("Prezzo");
      QName foto = new QName("Foto");
      QName web = new QName("Web");
      QName tessera = new QName("Tessera");
      
      String query = "//Evento";

      	query+="[@hp=\"false\"  and ((DataFine != \"\" and xs:date(DataFine) < xs:date(\""+quando+"\") ) or (@settimanale=\"true\") or (Data != \"\" and Data = DataFine and xs:date(Data) >= xs:date(\""+oggi+"\") and xs:date(Data) < xs:date(\""+quando+"\")) )]";
  
      
      try{
      	//System.out.println(query);
    	  builder.build(new File(url+File.separator+"Eventi.xml"));    
	      selector = xpath.compile(query).load(); 
	      selector.setContextItem(eventiDoc);
      }
	      catch (Exception e) {
	 			
	 			e.printStackTrace();
	 			getLog().error(e.toString());
	    	  return eventi;
	      } 

	          for (XdmItem item: selector) {
	        	  
	        	  Evento ev = new Evento();
	        	  String hpVal = ((XdmNode)item).getAttributeValue(hp);
	        	  String settVal = ((XdmNode)item).getAttributeValue(settimanale);
	        	  String catVal = ((XdmNode)item).getAttributeValue(categoria);
	        	  String idVal = ((XdmNode)item).getAttributeValue(id);
	        	  String tipoVal = ((XdmNode)item).getAttributeValue(tipo);
	              XdmNode dataVal = getChild((XdmNode)item, data);
	              XdmNode dataFineVal = getChild((XdmNode)item, dataFine);
	              String oraInizio = dataVal.getAttributeValue(ora);
	              String oraFine = dataFineVal.getAttributeValue(ora);	              
	              XdmNode giornoVal = getChild((XdmNode)item, giorno);
	              XdmNode oraVal = getChild((XdmNode)item, ora);
	              XdmNode indirizzoVal = getChild((XdmNode)item, indirizzo);
	              XdmNode nomeLuogoVal = getChild((XdmNode)item,nomeLuogo);
	              XdmNode titoloVal = getChild((XdmNode)item, titolo);
	              XdmNode keywordsVal = getChild((XdmNode)item, keywords);
	              XdmNode descrizioneVal = getChild((XdmNode)item, descrizione);
	              XdmNode descBreveVal = getChild((XdmNode)item, descBreve);
	              XdmNode prezzoVal = getChild((XdmNode)item, prezzo);
	              XdmNode fotoVal = getChild((XdmNode)item, foto);
	              XdmNode webVal = getChild((XdmNode)item, web);
	              XdmNode tesseraVal = getChild((XdmNode)item, tessera);

	              //Setting Evento 
	              if(hpVal.equalsIgnoreCase("true"))
					ev.setHp(true);
	              else
					ev.setHp(false);	  
	              if(settVal.equalsIgnoreCase("true"))
					ev.setSettimanale(true);
	              else
					ev.setSettimanale(false);
	             
	              if(tesseraVal.getStringValue().equalsIgnoreCase("true"))
						ev.setTessera(true);
		              else
						ev.setTessera(false);
	              
	              ev.setCategoria(catVal);
	              ev.setTipo(tipoVal);
	              //ID
	              int  num = Integer.parseInt(idVal);
	              if(num==-1)
	            	  continue;
	              ev.setId(num);
	              //DATA
	              String dataTemp = dataVal.getStringValue();
	              Date dataPars = Utility.toDateDataXml(dataTemp);
	              if(dataPars!=null){
	            	  Calendar greg = GregorianCalendar.getInstance(Utility.timeZone);
		              Date oraIn = Utility.toDateOra(oraInizio);
		              greg.setTime(oraIn);
		              
	            	  Calendar grego = GregorianCalendar.getInstance(Utility.timeZone);
		              grego.setTime(dataPars);
		              grego.set(GregorianCalendar.HOUR_OF_DAY, greg.get(GregorianCalendar.HOUR_OF_DAY));
		              grego.set(GregorianCalendar.MINUTE, greg.get(GregorianCalendar.MINUTE));
		              dataPars = grego.getTime();
	              }
	              
	              ev.setData(dataPars);
	              //data FINE
	              String dataT = dataFineVal.getStringValue();
	              Date dataF = Utility.toDateDataXml(dataT);
	              if(dataF!=null){
	            	  Calendar greg = GregorianCalendar.getInstance(Utility.timeZone);
		              Date oraFin = Utility.toDateOra(oraFine);
		              greg.setTime(oraFin);
		              
	            	  Calendar grego = GregorianCalendar.getInstance(Utility.timeZone);
		              grego.setTime(dataF);
		              grego.set(GregorianCalendar.HOUR_OF_DAY, greg.get(GregorianCalendar.HOUR_OF_DAY));
		              grego.set(GregorianCalendar.MINUTE, greg.get(GregorianCalendar.MINUTE));
		              dataF = grego.getTime();
	              }
	              ev.setDataFine(dataF);
	              //ORA
	              String Ora = oraVal.getStringValue();
	              Date Hora = Utility.toDateOra(Ora);
	              ev.setOra(Hora);
	              
	              //RESTO
	              ev.setIndirizzo(indirizzoVal.getStringValue());
	              ev.setNomeLuogo(nomeLuogoVal.getStringValue());
	              ev.setTitolo(titoloVal.getStringValue());
	              ev.setKeywords(keywordsVal.getStringValue());
	              ev.setDescrizione(descrizioneVal.getStringValue());
	              ev.setDescrizioneBreve(descBreveVal.getStringValue());
	              ev.setPrezzo(prezzoVal.getStringValue());
	              ev.setFoto(fotoVal.getStringValue());
	              ev.setGiorno(giornoVal.getStringValue());
	              ev.setWeb(webVal.getStringValue());

	              //ev.setOra(oraVal.getStringValue());
	          
	              eventi.add(ev);
	          }
			
		    

return eventi;

	 }
}
